热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql学习|LeetCode数据库简单查询练习

力扣:https:leetcode-cn.com力扣网数据库练习:https:leetcode-cn.comproblemsetdatabase文章目录

力扣:https://leetcode-cn.com/
力扣网数据库练习:https://leetcode-cn.com/problemset/database/

文章目录

        • 175. 组合两个表
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:on与where的区别
        • 176. 第二高的薪水
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:关于解题思路与limit、isnull等
        • 177. 第N高的薪水
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:limit x,y 语句用法
        • 181. 超过经理收入的员工
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:子查询解法
        • 182. 查找重复的电子邮箱
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:语句执行顺序
        • 183. 从不订购的客户
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
        • 196. 删除重复的电子邮箱
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:`You can't specify target table 'Person' for update in FROM clause`
        • 197. 上升的温度
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:时间函数



练习主要以LeetCode上数据库练习题简单题为例,以下分别提供对应题目的官方题解和在提交列表中执行最快的mysql查询语句。


175. 组合两个表

题目连接:https://leetcode-cn.com/problems/combine-two-tables/

Create table Person (PersonId int, FirstName varchar(255), LastName varchar(255))
Create table Address (AddressId int, PersonId int, City varchar(255), State varchar(255))
Truncate table Person
insert into Person (PersonId, LastName, FirstName) values ('1', 'Wang', 'Allen')
Truncate table Address
insert into Address (AddressId, PersonId, City, State) values ('1', '2', 'New York City', 'New York')

表1: Person

+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| PersonId | int |
| FirstName | varchar |
| LastName | varchar |
+-------------+---------+

PersonId 是上表主键

表2: Address

+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
+-------------+---------+

AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:

FirstName, LastName, City, State

题解:

1. LeetCode官方题解

方法:使用 outer join
算法

因为表 Address 中的 personId 是表 Person 的外关键字,所以我们可以连接这两个表来获取一个人的地址信息。

考虑到可能不是每个人都有地址信息,我们应该使用 outer join 而不是默认的 inner join。

select FirstName, LastName, City, State
from Person left join Address
on Person.PersonId = Address.PersonId
;作者:LeetCode
链接:https://leetcode-cn.com/problems/combine-two-tables/solution/zu-he-liang-ge-biao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

注意:如果没有某个人的地址信息,使用 where 子句过滤记录将失败,因为它不会显示姓名信息。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select A.FirstName, A.LastName, B.City, B.State
from Person A
left join (select distinct PersonId, City, State from Address) B
on A.PersonId=B.PersonId;

笔记:on与where的区别

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下:

1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉

——来自评论: Carl Marx



176. 第二高的薪水

题目链接:https://leetcode-cn.com/problems/second-highest-salary/

Create table If Not Exists Employee (Id int, Salary int)
Truncate table Employee
insert into Employee (Id, Salary) values ('1', '100')
insert into Employee (Id, Salary) values ('2', '200')
insert into Employee (Id, Salary) values ('3', '300')

编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。

+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+

例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+

题解:

1. LeetCode官方题解

方法一:使用子查询和 LIMIT 子句
算法:将不同的薪资按降序排序,然后使用 LIMIT 子句获得第二高的薪资。

SELECT(SELECT DISTINCTSalaryFROMEmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1) AS SecondHighestSalary
;

然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表。

SELECT(SELECT DISTINCTSalaryFROMEmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1) AS SecondHighestSalary
;

方法二:使用 IFNULL 和 LIMIT 子句
解决 “NULL” 问题的另一种方法是使用 “IFNULL” 函数,如下所示。

SELECTIFNULL((SELECT DISTINCT SalaryFROM EmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1),NULL) AS SecondHighestSalary-------------------------------------------------------------------
作者:LeetCode
链接:https://leetcode-cn.com/problems/second-highest-salary/solution/di-er-gao-de-xin-shui-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select ifNull((select distinct Salary from Employee order by Salary desc limit 1,1),null) as SecondHighestSalary;

笔记:关于解题思路与limit、isnull等

注意:考虑到有重复值的情况,使用distinct 成绩进行成绩去重。

  • 思路一:使用(IRDER BY)将数据降序排列,利用(LIMIT n1,n2)返回 n1~n2间的数据。
    select (select distinct salary from Employee order by salary desc limit 1,1) as SecondHighestSalary;
  • 思路二:使用聚合函数 max(列名) ,获得最高薪水,再将数据降序排列,则第一个小于 max 的数据为第二高分。
    select max(Salary) SecondHighestSalary from employee where salary<(select max(salary) from employee);

mysql语句分析&#xff1a;

  • limit n子句表示查询结果返回前n条数据
  • offset n表示跳过x条语句
  • limit y offset x 分句表示查询结果跳过 x 条数据&#xff0c;读取前 y 条数据
  • 使用limit和offset&#xff0c;降序排列再返回第二条记录可以得到第二大的值。

考虑特殊情况 isnull()

题目要求&#xff0c;如果没有第二高的成绩&#xff0c;返回空值&#xff0c;所以这里用判断空值的函数&#xff08;ifnull&#xff09;函数来处理特殊情况。
ifnull(a,b)函数解释&#xff1a;
如果value1不是空&#xff0c;结果返回a, 如果value1是空&#xff0c;结果返回b
select ifnull((select 子句),null) as &#39;别名&#39;;

select IFNULL((select distinct(Salary) from Employee order by Salary desc limit 1,1),null) as SecondHighestSalary;



177. 第N高的薪水

题目链接&#xff1a;https://leetcode-cn.com/problems/nth-highest-salary/
编写一个 SQL 查询&#xff0c;获取 Employee 表中第 n 高的薪水&#xff08;Salary&#xff09;。

&#43;----&#43;--------&#43;
| Id | Salary |
&#43;----&#43;--------&#43;
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
&#43;----&#43;--------&#43;

例如上述 Employee 表&#xff0c;n &#61; 2 时&#xff0c;应返回第二高的薪水 200。如果不存在第 n 高的薪水&#xff0c;那么查询应返回 null。

&#43;------------------------&#43;
| getNthHighestSalary(2) |
&#43;------------------------&#43;
| 200 |
&#43;------------------------&#43;

题解&#xff1a;

1. LeetCode官方题解

解题思路

  1. 通过自定义变量&#xff0c;对按薪水降序后的数据进行排名&#xff0c;其中同薪同名&#xff0c;连续排名&#xff0c;即形如1、2、2、3&#xff1b;
  2. 对具有排名信息的临时表二次筛选&#xff0c;得到排名为N的薪水&#xff1b;
  3. 因为薪水排名为N的记录可能不止1个&#xff0c;用distinct去重

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINRETURN (# Write your MySQL query statement below.SELECT DISTINCT salary FROM (SELECT salary, &#64;r:&#61;IF(&#64;p&#61;salary, &#64;r, &#64;r&#43;1) AS &#39;rank&#39;, &#64;p:&#61; salary FROM employee, (SELECT &#64;r:&#61;0, &#64;p:&#61;NULL)init ORDER BY salary DESC) tmpWHERE rank &#61; N);
END-------------------------------------------------------------------
作者&#xff1a;luanz
链接&#xff1a;https://leetcode-cn.com/problems/nth-highest-salary/solution/mysql-zi-ding-yi-bian-liang-by-luanz/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
set n &#61; n-1;RETURN (# Write your MySQL query statement below.select distinct Salary from Employee order by Salary desc limit n,1);
END

笔记&#xff1a;limit x,y 语句用法

此题与 176. 第二高的薪水 类型相同&#xff0c;可以使用 limit n1,n2 语句&#xff0c;取n1~n2之间的数据。

另外&#xff0c;对MySQL来说&#xff0c; limit x,y &#61; limit y offset x。
SQL查询语句中的 limit 与 offset 的区别&#xff1a;

  • limit y 分句表示: 读取 y 条数据
  • limit x, y 分句表示: 跳过 x 条数据&#xff0c;读取 y 条数据
  • limit y offset x 分句表示: 跳过 x 条数据&#xff0c;读取 y 条数据

-- 例1&#xff1a;从第0个开始&#xff0c;获取20条数据
select * from testtable limit 0, 20;
select * from testtable limit 20 offset 0;
-- 例2&#xff1a; 从第20个开始&#xff0c;获取20条数据
select * from testtable limit 20, 20;
select * from testtable limit 20 offset 20;
-- 例3&#xff1a; 从第40个开始&#xff0c;获取20条数据
select * from testtable limit 40, 20;
select * from testtable limit 20 offset 40;

——参考自博文&#xff1a; SQL查询语句中的 limit 与 offset 的区别


如此题中&#xff0c;选用第n高的薪水。我们只需先将n设置为n-1&#xff08;表中数据从0开始排列&#xff09;&#xff0c;然后使用 limt n,1 从第n个数据开始获取一条数据即可。

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINSET N &#61; N - 1;RETURN (# Write your MySQL query statement below.select (select distinct salary from employee order by salary desclimit N,1));
END



181. 超过经理收入的员工

题目链接&#xff1a;https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/

Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, ManagerId int)
Truncate table Employee
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;1&#39;, &#39;Joe&#39;, &#39;70000&#39;, &#39;3&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;2&#39;, &#39;Henry&#39;, &#39;80000&#39;, &#39;4&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;3&#39;, &#39;Sam&#39;, &#39;60000&#39;, &#39;None&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;4&#39;, &#39;Max&#39;, &#39;90000&#39;, &#39;None&#39;)

Employee 表包含所有员工&#xff0c;他们的经理也属于员工。每个员工都有一个 Id&#xff0c;此外还有一列对应员工的经理的 Id。

&#43;----&#43;-------&#43;--------&#43;-----------&#43;
| Id | Name | Salary | ManagerId |
&#43;----&#43;-------&#43;--------&#43;-----------&#43;
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | NULL |
| 4 | Max | 90000 | NULL |
&#43;----&#43;-------&#43;--------&#43;-----------&#43;

给定 Employee 表&#xff0c;编写一个 SQL 查询&#xff0c;该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中&#xff0c;Joe 是唯一一个收入超过他的经理的员工。

&#43;----------&#43;
| Employee |
&#43;----------&#43;
| Joe |
&#43;----------&#43;

题解&#xff1a;

1. LeetCode官方题解

方法1&#xff1a;使用 WHERE 语句
算法:

如下面表格所示&#xff0c;表格里存有每个雇员经理的信息&#xff0c;我们也许需要从这个表里获取两次信息。

SELECT *
FROM Employee AS a, Employee AS b
;

注意&#xff1a;关键词 ‘AS’ 是可选的

IdNameSalaryManagerIdIdNameSalaryManagerId
1Joe7000031Joe700003
2Henry8000041Joe700003
3Sam600001Joe700003
4Max900001Joe700003
1Joe7000032Henry800004
2Henry8000042Henry800004
3Sam600002Henry800004
4Max900002Henry800004
1Joe7000033Sam60000
2Henry8000043Sam60000
3Sam600003Sam60000
4Max900003Sam60000
1Joe7000034Max90000
2Henry8000044Max90000
3Sam600004Max90000
4Max900004Max90000

前 3 列来自表格 a &#xff0c;后 3 列来自表格 b

从两个表里使用 Select 语句可能会导致产生 笛卡尔乘积 。在这种情况下&#xff0c;输出会产生 4*4&#61;16 个记录。然而我们只对雇员工资高于经理的人感兴趣。所以我们应该用 WHERE 语句加 2 个判断条件。

SELECT*
FROMEmployee AS a,Employee AS b
WHEREa.ManagerId &#61; b.IdAND a.Salary > b.Salary
;

IdNameSalaryManagerIdIdNameSalaryManagerId
1Joe7000033Sam60000

由于我们只需要输出雇员的名字&#xff0c;所以我们修改一下上面的代码&#xff0c;得到最终解法&#xff1a;

SELECTa.Name AS &#39;Employee&#39;
FROMEmployee AS a,Employee AS b
WHEREa.ManagerId &#61; b.IdAND a.Salary > b.Salary
;

方法 2&#xff1a;使用 JOIN 语句
算法:

实际上&#xff0c; JOIN 是一个更常用也更有效的将表连起来的办法&#xff0c;我们使用 ON 来指明条件。

SELECTa.NAME AS Employee
FROM Employee AS a JOIN Employee AS bON a.ManagerId &#61; b.IdAND a.Salary > b.Salary
;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/solution/chao-guo-jing-li-shou-ru-de-yuan-gong-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

以上两种写法&#xff0c;一种是直接对两表

# Write your MySQL query statement below
select e.Name Employee
from Employee e left join (select distinct Id,Salary from Employee) m on e.ManagerId &#61; m.Id
where e.Salary > m.Salary

笔记&#xff1a;子查询解法

官方题解一采用直接对两表进行笛卡尔积&#xff0c;而后对结果使用WHERE筛选出符合条件的数据&#xff0c;官方题解二使用内连接的方式对临时表过滤筛选。除此之外&#xff0c;我们还可以使用子查询语句解决问题。

SELECT Name Employee
FROMEmployee AS e
WHERESalary > (SELECT SalaryFROMEmployeeWHEREId &#61; e.Managerid)



182. 查找重复的电子邮箱

题目链接&#xff1a;https://leetcode-cn.com/problems/duplicate-emails/

Create table If Not Exists Person (Id int, Email varchar(255))
Truncate table Person
insert into Person (Id, Email) values (&#39;1&#39;, &#39;a&#64;b.com&#39;)
insert into Person (Id, Email) values (&#39;2&#39;, &#39;c&#64;d.com&#39;)
insert into Person (Id, Email) values (&#39;3&#39;, &#39;a&#64;b.com&#39;)

编写一个 SQL 查询&#xff0c;查找 Person 表中所有重复的电子邮箱。

示例&#xff1a;

&#43;----&#43;---------&#43;
| Id | Email |
&#43;----&#43;---------&#43;
| 1 | a&#64;b.com |
| 2 | c&#64;d.com |
| 3 | a&#64;b.com |
&#43;----&#43;---------&#43;

根据以上输入&#xff0c;你的查询应返回以下结果&#xff1a;

&#43;---------&#43;
| Email |
&#43;---------&#43;
| a&#64;b.com |
&#43;---------&#43;

说明&#xff1a;所有电子邮箱都是小写字母。

题解&#xff1a;

1. LeetCode官方题解

方法一&#xff1a;使用 GROUP BY 和临时表
算法:

重复的电子邮箱存在多次。要计算每封电子邮件的存在次数&#xff0c;我们可以使用以下代码。

MySQL
select Email, count(Email) as num
from Person
group by Email;

Emailnum
a&#64;b.com2
c&#64;d.com1

以此作为临时表&#xff0c;我们可以得到下面的解决方案。

MySQL
select Email from
(select Email, count(Email) as numfrom Persongroup by Email
) as statistic
where num > 1
;

方法二&#xff1a;使用 GROUP BY 和 HAVING 条件
向 GROUP BY 添加条件的一种更常用的方法是使用 HAVING 子句&#xff0c;该子句更为简单高效。

所以我们可以将上面的解决方案重写为&#xff1a;

MySQL
select Email
from Person
group by Email
having count(Email) > 1;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/duplicate-emails/solution/cha-zhao-zhong-fu-de-dian-zi-you-xiang-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
Select Email from Person
Group by Email
Having Count(Email)>1

笔记&#xff1a;语句执行顺序

在使用group by、having等语句是要注意它们的执行顺序。
执行顺序 &#xff1a;from > on > where > group by > having > select > distinct > order by > top

当一个查询语句同时出现了where,group by,having,order by的时候&#xff0c;执行顺序和编写顺序是&#xff1a;
1.执行where xx对全表数据做筛选&#xff0c;返回第1个结果集。
2.针对第1个结果集使用group by分组&#xff0c;返回第2个结果集。
3.针对第2个结集执行having xx进行筛选&#xff0c;返回第3个结果集。
4.针对第3个结果集中的每1组数据执行select xx&#xff0c;有几组就执行几次&#xff0c;返回第4个结果集。
5.针对第4个结果集排序。

——参考自博文&#xff1a;where、having、group by、order by执行和书写顺序



183. 从不订购的客户

题目链接&#xff1a;https://leetcode-cn.com/problems/customers-who-never-order/

Create table If Not Exists Customers (Id int, Name varchar(255))
Create table If Not Exists Orders (Id int, CustomerId int)
Truncate table Customers
insert into Customers (Id, Name) values (&#39;1&#39;, &#39;Joe&#39;)
insert into Customers (Id, Name) values (&#39;2&#39;, &#39;Henry&#39;)
insert into Customers (Id, Name) values (&#39;3&#39;, &#39;Sam&#39;)
insert into Customers (Id, Name) values (&#39;4&#39;, &#39;Max&#39;)
Truncate table Orders
insert into Orders (Id, CustomerId) values (&#39;1&#39;, &#39;3&#39;)
insert into Orders (Id, CustomerId) values (&#39;2&#39;, &#39;1&#39;)

某网站包含两个表&#xff0c;Customers 表和 Orders 表。编写一个 SQL 查询&#xff0c;找出所有从不订购任何东西的客户。

Customers 表&#xff1a;

&#43;----&#43;-------&#43;
| Id | Name |
&#43;----&#43;-------&#43;
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
&#43;----&#43;-------&#43;

Orders 表&#xff1a;

&#43;----&#43;------------&#43;
| Id | CustomerId |
&#43;----&#43;------------&#43;
| 1 | 3 |
| 2 | 1 |
&#43;----&#43;------------&#43;

例如给定上述表格&#xff0c;你的查询应返回&#xff1a;

&#43;-----------&#43;
| Customers |
&#43;-----------&#43;
| Henry |
| Max |
&#43;-----------&#43;

题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用子查询和 NOT IN 子句
算法&#xff1a;如果我们有一份曾经订购过的客户名单&#xff0c;就很容易知道谁从未订购过。

我们可以使用下面的代码来获得这样的列表。

select customerid from orders;

然后&#xff0c;我们可以使用 NOT IN 查询不在此列表中的客户。

select customers.name as &#39;Customers&#39;
from customers
where customers.id not in
(select customerid from orders
);-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/customers-who-never-order/solution/cong-bu-ding-gou-de-ke-hu-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select Customers.Name as Customers
from Customers
where Id not in
(select distinct CustomerId from Orders
)



196. 删除重复的电子邮箱

题目链接&#xff1a;https://leetcode-cn.com/problems/delete-duplicate-emails/

编写一个 SQL 查询&#xff0c;来删除 Person 表中所有重复的电子邮箱&#xff0c;重复的邮箱里只保留 Id 最小 的那个。

&#43;----&#43;------------------&#43;
| Id | Email |
&#43;----&#43;------------------&#43;
| 1 | john&#64;example.com |
| 2 | bob&#64;example.com |
| 3 | john&#64;example.com |
&#43;----&#43;------------------&#43;

Id 是这个表的主键。
例如&#xff0c;在运行你的查询语句之后&#xff0c;上面的 Person 表应返回以下几行:

&#43;----&#43;------------------&#43;
| Id | Email |
&#43;----&#43;------------------&#43;
| 1 | john&#64;example.com |
| 2 | bob&#64;example.com |
&#43;----&#43;------------------&#43;

提示&#xff1a;

执行 SQL 之后&#xff0c;输出是整个 Person 表。
使用 delete 语句。


题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用 DELETE 和 WHERE 子句
算法: 我们可以使用以下代码&#xff0c;将此表与它自身在电子邮箱列中连接起来。

SELECT p1.*
FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email
;

然后我们需要找到其他记录中具有相同电子邮件地址的更大 ID。所以我们可以像这样给 WHERE 子句添加一个新的条件。

SELECT p1.*
FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email AND p1.Id > p2.Id
;

因为我们已经得到了要删除的记录&#xff0c;所以我们最终可以将该语句更改为 DELETE。

MySQL
DELETE p1 FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email AND p1.Id > p2.Id-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/delete-duplicate-emails/solution/shan-chu-zhong-fu-de-dian-zi-you-xiang-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
DELETE FROM Person
WHERE Id NOT IN
( SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P
)

笔记&#xff1a;You can&#39;t specify target table &#39;Person&#39; for update in FROM clause

方法二&#xff1a;查询出所有的邮箱的最小Id&#xff0c;则不再此列表中的Id都重复Id。

报错&#xff1a;You can’t specify target table ‘Person’ for update in FROM clause&#xff0c;是因为&#xff1a;
mysql不支持对同一个表进行delete(update)和select操作&#xff0c;必须将查询结果保留进一个新表里&#xff0c;再次select&#xff0c;并且select出的表必须有一个自己的别名。

因此&#xff0c;我们在子查询中的查询到的临时表还需要进行再封装。

SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P

此表返回的结果集是所有不同邮箱的最小Id&#xff0c;接下来只需找到不再此列表中的Id即是我们需要删去的重复Id。

DELETE FROM Person
WHERE Id NOT IN
( SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P
)



197. 上升的温度

题目链接&#xff1a;https://leetcode-cn.com/problems/rising-temperature/

Create table If Not Exists Weather (Id int, RecordDate date, Temperature int)
Truncate table Weather
insert into Weather (Id, RecordDate, Temperature) values (&#39;1&#39;, &#39;2015-01-01&#39;, &#39;10&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;2&#39;, &#39;2015-01-02&#39;, &#39;25&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;3&#39;, &#39;2015-01-03&#39;, &#39;20&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;4&#39;, &#39;2015-01-04&#39;, &#39;30&#39;)

给定一个 Weather 表&#xff0c;编写一个 SQL 查询&#xff0c;来查找与之前&#xff08;昨天的&#xff09;日期相比温度更高的所有日期的 Id。

&#43;---------&#43;------------------&#43;------------------&#43;
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
&#43;---------&#43;------------------&#43;------------------&#43;
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
&#43;---------&#43;------------------&#43;------------------&#43;

例如&#xff0c;根据上述给定的 Weather 表格&#xff0c;返回如下 Id:

&#43;----&#43;
| Id |
&#43;----&#43;
| 2 |
| 4 |
&#43;----&#43;

题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用 JOIN 和 DATEDIFF() 子句
算法: MySQL 使用 DATEDIFF 来比较两个日期类型的值。

因此&#xff0c;我们可以通过将 weather 与自身相结合&#xff0c;并使用 DATEDIFF() 函数。

MySQL
SELECTweather.id AS &#39;Id&#39;
FROMweatherJOINweather w ON DATEDIFF(weather.date, w.date) &#61; 1AND weather.Temperature > w.Temperature
;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/rising-temperature/solution/shang-sheng-de-wen-du-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select tmp.Id
from (select Id, &#64;flag :&#61; if((Temperature > &#64;preTemperature and &#64;PreDate &#61; DATE_SUB(RecordDate, INTERVAL 1 DAY)), True, False) as flag, &#64;preTemperature :&#61; Temperature, &#64;PreDate :&#61; RecordDatefrom Weather, (select &#64;flag :&#61; False, &#64;preTemperature :&#61; NULL, &#64;PreDate :&#61; NULL) forder by RecordDate
) tmp
where tmp.flag &#61; 1

# Write your MySQL query statement below
SELECT a.Id
FROM (SELECT w.Id, w.Temperature, if(w.Temperature > &#64;last_TAND datediff(w.RecordDate, &#64;last_D) &#61; 1, 1, 0) AS is_greater, &#64;last_T :&#61; w.Temperature, &#64;last_D :&#61; w.RecordDateFROM Weather w, (SELECT &#64;last_T :&#61; 100, &#64;last_D :&#61; 1) bORDER BY RecordDate ASC
) a
WHERE a.is_greater &#61; 1
ORDER BY a.Id ASC

笔记&#xff1a;时间函数

常用时间函数&#xff1a;

CURDATE()返回当前日期
CURTIME()返回当前时间
NOW()返回当前的日期和时间
UNIX_TIMESTAMP(date)返回日期date的UNIX时间戳
FROM_UNIXTIME返回UNIX时间戳的日期值
WEEK(date)返回日期date为一年中的第几周
YEAR(date)返回日期date的年份
HOUR(time)返回time的小时值
MINUTE(time)返回time的分钟值
MONTHNAME(date)返回date的月份名
DATE_FORMAT(date,fmt)返回按字符串fmt格式化日期date值
DATE_ADD(date,INTERVAL expr type)返回一个日期或时间值加上- -个时间间隔的时间值
DATEDIFF(expr,expr2)返回起始时间expr 和结束时间expr2之间的天数

时间函数&#xff1a;https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate


推荐阅读
  • MySQL多表数据库操作方法及子查询详解
    本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • php设置数组大小_【大厂必备】2020超经典PHP面试题
    结合我自己这段时间的面试情况,面对的一些php面试题列举出来,基本上结合自己的看法回答的,不妥的地方请大家指出去,与大家一起 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 本文主要介绍了MySQL中子查询的基本用法和三种用法,包括生成参考值、内层查询与外层查询的比较操作以及使用事件号在成绩表中找到学生的分数记录。通过详细解析子查询的实例,帮助读者更好地理解和应用子查询。 ... [详细]
  • 从批量eml文件中提取附件的Python代码实现方法
    本文介绍了使用Python代码从批量eml文件中提取附件的实现方法,包括获取eml附件信息、递归文件夹下所有文件、创建目的文件夹等步骤。通过该方法可以方便地提取eml文件中的附件,并保存到指定的文件夹中。 ... [详细]
author-avatar
mobiledu2502916347
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有